package me.sdevil507.biz.common.sysdict.service.impi;

import com.google.common.collect.Lists;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.StringTemplate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import me.sdevil507.biz.common.sysdict.po.QSysDict;
import me.sdevil507.biz.common.sysdict.po.SysDict;
import me.sdevil507.biz.common.sysdict.repository.SysDictRepository;
import me.sdevil507.biz.common.sysdict.service.SysdictService;
import me.sdevil507.supports.jpa.PageParamsDTO;
import me.sdevil507.supports.jpa.SortParamsDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @program: tips_back_end
 * @description: 字典实现类
 * @author: kzl
 * @create: 2020-06-29 11:26
 **/
@Service
@Slf4j
@CacheConfig(cacheNames = "sysDict")
public class SysdictServiceImpl implements SysdictService {

    @Resource
    private SysDictRepository sysDictRepository;

    @Autowired
    JPAQueryFactory jpaQueryFactory;

    @Cacheable(cacheNames = "sysDictList", key = "'typeKey_' + #p0")
    @Override
    public List<SysDict> findByTypeKey(String typeKey) {
        log.info("sysDictList无缓存时执行下面代码，获取字典表数据,Time：" + new Date());
//        QSysDict sysDict = QSysDict.sysDict;
//        return jpaQueryFactory.selectFrom(sysDict).where(sysDict.typeKey.eq(typeKey)).orderBy(sysDict.dvalue.asc()).fetch();
        return sysDictRepository.getAllSysDictData(typeKey);
    }

    @CacheEvict(cacheNames = "sysDictList", key = "'typeKey_' + #p0")
    @Override
    public void deleteByTypeKey(String typeKey) {
    }

    @Override
    public List<SysDict> findByTypeKeyAndValue(String typeKey,String dvalue) {

        QSysDict sysDict = QSysDict.sysDict;
        return jpaQueryFactory.selectFrom(sysDict).where(sysDict.typeKey.eq(typeKey)).where(sysDict.dvalue.eq(dvalue)).fetch();

    }

    @Override
    public List<SysDict> findByTypeKeyAndName(String typeKey, String dname) {
        QSysDict sysDict = QSysDict.sysDict;
        return jpaQueryFactory.selectFrom(sysDict).where(sysDict.typeKey.eq(typeKey)).where(sysDict.dname.eq(dname)).fetch();
    }

    @Override
    public void create(SysDict sysDict) {
        sysDictRepository.save(sysDict);
    }

    @Override
    public void delete(SysDict sysDict) {
        sysDictRepository.logicDelete(sysDict.getId());
        sysDictRepository.logicDeleteByParentId(sysDict.getId());
    }

    @Override
    public List<SysDict> findExistsByName(String name, Long parentId,Long id) {

        QSysDict sysDict = QSysDict.sysDict;
        if(null!=id && id.longValue()>0){
            return jpaQueryFactory.selectFrom(sysDict).where(sysDict.parentId.eq(parentId)).where(sysDict.dname.eq(name)).where(sysDict.isDel.eq(false)).where(sysDict.id.ne(id)).fetch();
        }else{
            return jpaQueryFactory.selectFrom(sysDict).where(sysDict.parentId.eq(parentId)).where(sysDict.dname.eq(name)).where(sysDict.isDel.eq(false)).fetch();

        }
    }

    @Override
    public List<SysDict> findExistsByCode(String code, Long parentId,Long id) {

        QSysDict sysDict = QSysDict.sysDict;
        if(null!=id && id.longValue()>0){
            return jpaQueryFactory.selectFrom(sysDict).where(sysDict.parentId.eq(parentId)).where(sysDict.dcode.eq(code)).where(sysDict.isDel.eq(false)).where(sysDict.id.ne(id)).fetch();
        }else {
            return jpaQueryFactory.selectFrom(sysDict).where(sysDict.parentId.eq(parentId)).where(sysDict.dcode.eq(code)).where(sysDict.isDel.eq(false)).fetch();

        }
    }

    @Override
    public List<SysDict> readAll(SysDict searchDTO, SortParamsDTO sortParamsDto) {
        QSysDict sysDict = QSysDict.sysDict;
        // 开启谓语查询条件
        Predicate predicate = sysDict.id.isNotNull();

        //dname
        String name = searchDTO.getDname();
        if (!StringUtils.isEmpty(name)) {
            predicate = ExpressionUtils.and(predicate, sysDict.dname.like("%" + name + "%"));
        }

        //类型
        String typeKey = searchDTO.getTypeKey();
        if (!StringUtils.isEmpty(typeKey)) {
            predicate = ExpressionUtils.and(predicate, sysDict.typeKey.eq(typeKey));
        }

        //dcode
        String dcode = searchDTO.getDcode();
        if (!StringUtils.isEmpty(dcode)) {
            predicate = ExpressionUtils.and(predicate, sysDict.dcode.eq(dcode));
        }

        //dcode
        String dvalue = searchDTO.getDvalue();
        if (!StringUtils.isEmpty(dvalue)) {
            predicate = ExpressionUtils.and(predicate, sysDict.dvalue.eq(dvalue));
        }

        //parentId
        Long parentId = searchDTO.getParentId();
        if (null != parentId && parentId.longValue() > 0) {
            predicate = ExpressionUtils.and(predicate, sysDict.parentId.eq(parentId));
        }

        Sort sort;
        if (null == sortParamsDto) {
            sort = Sort.by(Sort.Direction.ASC, "createTime");
        } else {
            // 排序
            sort = sortParamsDto.getSort();
            if (null == sort) {
                sort = Sort.by(Sort.Direction.ASC, "createTime");
            }
        }
        // 执行Iterable转换List
        List<SysDict> list = Lists.newArrayList(sysDictRepository.findAll(predicate, sort).iterator());
        return list;
    }

    @Override
    public Page<SysDict> readAllByPage(SysDict searchDTO, PageParamsDTO pageParamsDto, SortParamsDTO sortParamsDto) {
        QSysDict sysDict = QSysDict.sysDict;
        // 开启谓语查询条件
        Predicate predicate = sysDict.id.isNotNull();

        //dname
        String name = searchDTO.getDname();
        if (!StringUtils.isEmpty(name)) {
            predicate = ExpressionUtils.and(predicate, sysDict.dname.like("%" + name + "%"));
        }

        //类型
        String typeKey = searchDTO.getTypeKey();
        if (!StringUtils.isEmpty(typeKey)) {
            predicate = ExpressionUtils.and(predicate, sysDict.typeKey.eq(typeKey));
        }

        //dcode
        String dcode = searchDTO.getDcode();
        if (!StringUtils.isEmpty(dcode)) {
            predicate = ExpressionUtils.and(predicate, sysDict.dcode.eq(dcode));
        }

        //dcode
        String dvalue = searchDTO.getDvalue();
        if (!StringUtils.isEmpty(dvalue)) {
            predicate = ExpressionUtils.and(predicate, sysDict.dvalue.eq(dvalue));
        }

        //parentId
        Long parentId = searchDTO.getParentId();
        if (null != parentId && parentId.longValue() > 0) {
            predicate = ExpressionUtils.and(predicate, sysDict.parentId.eq(parentId));
        }

        Sort sort;
        if (null == sortParamsDto) {
            sort = Sort.by(Sort.Direction.DESC, "createTime");
        } else {
            // 排序
            sort = sortParamsDto.getSort();
            if (null == sort) {
                sort = Sort.by(Sort.Direction.DESC, "createTime");
            }
        }
        // 执行返回
        Pageable pageable = pageParamsDto.getPageableWithSort(sort);

        return sysDictRepository.findAll(predicate, pageable);
    }

    @Override
    public List<SysDict> readAllParent() {

        QSysDict sysDict = QSysDict.sysDict;
        return jpaQueryFactory.selectFrom(sysDict).where(sysDict.parentId.eq(new Long(1))).where(sysDict.isDel.eq(false)).fetch();

    }

    @Override
    public SysDict findOneById(Long id) {
        QSysDict sysDict = QSysDict.sysDict;
        return jpaQueryFactory.selectFrom(sysDict).where(sysDict.id.eq(id)).fetchOne();
    }

    @Override
    public SysDict findOneByCode(String code) {
        QSysDict sysDict = QSysDict.sysDict;
        return jpaQueryFactory.selectFrom(sysDict).where(sysDict.dcode.eq(code)).fetchOne();
    }

}